package cn.wen.yaling.xo.service.impl;

import cn.wen.yaling.commons.constant.RedisConstants;
import cn.wen.yaling.commons.enums.TagStatus;
import cn.wen.yaling.commons.service.RedisService;
import cn.wen.yaling.commons.utils.RedisUtils;
import cn.wen.yaling.commons.utils.ResultEntity;
import cn.wen.yaling.commons.vo.*;
import cn.wen.yaling.xo.dao.ArticleDao;
import cn.wen.yaling.xo.service.CommentService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yaling.commons.utils.PageUtils;
import cn.wen.yaling.commons.utils.Query;

import cn.wen.yaling.xo.dao.TagDao;
import cn.wen.yaling.commons.entity.TagEntity;
import cn.wen.yaling.xo.service.TagService;


@Service("tagService")
public class TagServiceImpl extends ServiceImpl<TagDao, TagEntity> implements TagService {


    @Autowired
    private TagDao tagDao;

    @Autowired
    private ArticleDao articleDao;

    @Autowired
    private CommentService commentService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<TagEntity> page = this.page(
                new Query<TagEntity>().getPage(params),
                new QueryWrapper<TagEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<ArticleListVO> getTagArticleList(Integer tagId) {
        List<ArticleListVO> articleList = articleDao.getTagArticleList(tagId);
        for (ArticleListVO articleListVO : articleList) {
            articleListVO.setCommentNum(commentService.getCommentNumByArticleId(articleListVO.getArticleId()));
        }
        return articleList;
    }

    @Override
    public List<TagVO> getAllTagList() {
        List<TagVO> tagVOS;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_TAG_LIST)) {
            tagVOS = redisUtils.getListCache(RedisConstants.CACHE_TAG_LIST, TagVO.class);
        } else {
            // 2、缓存不命中则到db中获取
            QueryWrapper<TagEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag_sort", 1);
            queryWrapper.eq("tag_status", TagStatus.NORMAL_USE.getStatus());
            queryWrapper.orderByAsc("tag_priority");
            List<TagEntity> tagEntities = tagDao.selectList(queryWrapper);
            tagVOS = new ArrayList<>();
            for (TagEntity tagEntity : tagEntities) {
                TagVO tagVO = new TagVO();
                // 获取每个标签的文章数量
                Integer count = tagDao.getCountByTagId(tagEntity.getTagId());
                BeanUtils.copyProperties(tagEntity, tagVO);
                tagVO.setArticleNum(count);
                tagVOS.add(tagVO);
            }
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_TAG_LIST, tagVOS);
        }
        return tagVOS;
    }

    @Override
    public List<Map<String, Object>> getBlogCountByTag() {
        // 获取全部在线的标签列表
        List<TagVO> tags = getAllTagList();
        List<Map<String, Object>> res = new ArrayList<>();
        for (TagVO tag : tags) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", tag.getTagName());
            map.put("value", tag.getArticleNum().longValue());
            map.put("tagId", tag.getTagId());
            res.add(map);
        }
        return res;
    }

    @Override
    public List<TagEntity> getTagList() {
        List<TagEntity> tagList;
        // 1、先判断redis缓存中是否能命中缓存
        if (redisService.hasKey(RedisConstants.CACHE_ADMIN_ALL_TAG_LIST)) {
            tagList = redisUtils.getListCache(RedisConstants.CACHE_ADMIN_ALL_TAG_LIST, TagEntity.class);
        } else {
            // 2、缓存不命中则到db中获取
            QueryWrapper<TagEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tag_sort", 1);
            queryWrapper.ne("tag_status", TagStatus.DELETED.getStatus() );
            queryWrapper.orderByAsc("tag_priority");
            tagList = tagDao.selectList(queryWrapper);
            // 3、将db中的缓存获取到
            redisUtils.setListCache(RedisConstants.CACHE_ADMIN_ALL_TAG_LIST, tagList);
        }
        return tagList;
    }

    @Override
    public List<TagEntity> getTagByTagName(String tagName) {
        QueryWrapper<TagEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tag_sort", 1);
        queryWrapper.ne("tag_status", TagStatus.DELETED.getStatus());
        queryWrapper.orderByAsc("tag_priority");
        queryWrapper.like("tag_name", tagName);
        List<TagEntity> tagEntities = tagDao.selectList(queryWrapper);
        return tagEntities;
    }

    @Override
    public ResultEntity updateTagStatus(Integer tagId, Integer status) {
        TagEntity target = new TagEntity();
        target.setTagStatus(status);
        target.setUpdateTime(new Date());
        target.setTagId(tagId);
        boolean res = tagDao.updateById(target) > 0;
        if (!res) return ResultEntity.error();
        // 删除缓存
        redisUtils.delTagListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity deleteTagByIds(Integer[] tagIds) {
        int res = tagDao.updateBatchIds(tagIds, TagStatus.DELETED.getStatus());
        if (res < 1) return ResultEntity.error();
        // 删除缓存
        redisUtils.delTagListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity updateTag(TagUpdateVO tag) {
        TagEntity target = new TagEntity();
        BeanUtils.copyProperties(tag, target);
        target.setUpdateTime(new Date());
        boolean res = tagDao.updateById(target) > 0;
        if (!res) return ResultEntity.error();
        // 删除缓存
        redisUtils.delTagListCache();
        return ResultEntity.ok();
    }

    @Override
    public ResultEntity addTag(TagAddVO tag) {
        TagEntity target = new TagEntity();
        BeanUtils.copyProperties(tag, target);
        target.setUpdateTime(new Date());
        target.setCreateTime(new Date());
        target.setTagStatus(TagStatus.NORMAL_USE.getStatus());
        target.setTagViewsNum(0);
        boolean res = tagDao.insert(target) > 0;
        if (!res) return ResultEntity.error();
        // 删除缓存
        redisUtils.delTagListCache();
        return ResultEntity.ok();
    }

}